﻿using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;

namespace Fee.Stores.Ef
{
    public class StationStore<T> : IStationStore<T> where T : FeeDbContext
    {
        private readonly T _context;

        public StationStore(T context)
        {
            _context = context;
        }

        public Station GetByCode(string code, bool track = true)
        {
            if (track)
                return _context.Stations.Include(_ => _.OrderDistrict)
                  .Include(_ => _.District).FirstOrDefault(_ => _.Code == code);
            else
            {
                return _context.Stations.Include(_ => _.OrderDistrict)
                    .Include(_ => _.District).AsNoTracking().FirstOrDefault(_ => _.Code == code);
            }
        }

        public Station GetById(int id)
        {
            return _context.Stations.Include(_ => _.OrderDistrict)
                .Include(_ => _.District).FirstOrDefault(_ => _.Id == id);
        }

        public IEnumerable<Station> List(StationSearcher searcher, out int total)
        {
            var query = _context.Stations.Include(f => f.District).Include(f => f.OrderDistrict)
                .Where(f =>
                    (string.IsNullOrEmpty(searcher.StationName) || f.Code.Contains(searcher.StationName))
                    && (searcher.DistrictId == null || searcher.DistrictId == f.District.Id)
                    && (searcher.Type == null || searcher.Type == f.Type)
                    && (searcher.Status == null || searcher.Status == f.Status)
                );

            total = query.Count();

            return query.Skip(searcher.GetSkip()).Take(searcher.GetTake());
        }

        public IEnumerable<Station> ListWithoutConsturctionTask(StationSearcher searcher, out int total)
        {
            var contextId = _context.ConstructionTasks.Select(f => f.Station.Id);
            var query = _context.Stations
                .Include(f => f.District)
                .Where(f =>
                    (string.IsNullOrEmpty(searcher.StationName) || f.Code.Contains(searcher.StationName))
                    && (searcher.DistrictId == null || searcher.DistrictId == f.District.Id)
                    && (searcher.Type == null || searcher.Type == f.Type)
                    && (searcher.Status == null || searcher.Status == f.Status)
                    && !contextId.Contains(f.Id)
                );

            total = query.Count();

            return query.Skip(searcher.GetSkip()).Take(searcher.GetTake());
        }
    }
}